//
// Created by wenda.zhao on 2023/2/24.
//

#include <string>
#include <sstream>
#include <utils/Log.h>
#include <sys/time.h>

#include "SequenceRecorder.h"

// 获取当前时间 
static std::string getCurrentFormatTime(){
    std::string stime;
    std::stringstream strtime;
    std::time_t currenttime = std::time(nullptr);
    char tAll[255];
    std::strftime(tAll, sizeof(tAll), "%Y%m%d_%H_%M_%S", std::localtime(&currenttime));
    strtime << tAll;
    stime = strtime.str();
    return stime;
}

SequenceRecorder::SequenceRecorder(android::PhysicalDisplayId displayId, const char *rootPath, int duration) {
    this->displayId = displayId;
    this->rootPath = rootPath;
    this->duration = duration;

    drOnStart = [this](const char *fileName) { SequenceRecorder::onNext(fileName); };
    drOnFinish = [this]() {SequenceRecorder::next();};
    drOnFail = [this](int errCode) { SequenceRecorder::onFail(errCode); };
}

std::string SequenceRecorder::getFileName() {
    std::string result;
    result.append(std::string(rootPath)).append(getCurrentFormatTime()).append(".mp4");
    std::string const &path = result;
    return path;
}

void SequenceRecorder::start() {
    auto *displayRecorder = new DisplayRecorder(displayId, getFileName(), duration);
    displayRecorder->setCallback(drOnStart, drOnFinish, drOnFail);
    currentRecorder = displayRecorder;
    if(currentRecorder != nullptr){
        currentRecorder->start();
    }
}

void SequenceRecorder::stop() {
    this->isStopped = true;
    if (currentRecorder != nullptr) {
        currentRecorder->stop();
    }
}

void SequenceRecorder::next() {
    if(currentRecorder != nullptr){
        currentRecorder->release();
        delete currentRecorder;
        currentRecorder = nullptr;
    }
    if (isStopped) {
        onFinish();
        return;
    }
    this->count++;
    start();
}

void SequenceRecorder::onNext(const char *fileName) {
    ALOGD("onNext %s ", fileName);
    if(this->onStartCallback != nullptr){
        this->onStartCallback(fileName);
    }
}

void SequenceRecorder::onFail(int errCode) {
    ALOGE("onFail %d ", errCode);
    if(this->onFailCallback != nullptr){
        this->onFailCallback(errCode);
    }
    stop();
}

void SequenceRecorder::onFinish() {
    ALOGD("onFinish");
    if(this->onFinishCallback != nullptr){
        this->onFinishCallback();
    }
}

void SequenceRecorder::setCallback(SequenceRecorder::OnStartCallback startCallback, SequenceRecorder::OnFinishCallback finishCallback,SequenceRecorder::OnFailCallback failCallback) {
    this->onStartCallback = std::move(startCallback);
    this->onFinishCallback = std::move(finishCallback);
    this->onFailCallback = std::move(failCallback);
}

SequenceRecorder::~SequenceRecorder() {
    delete rootPath;
    rootPath = nullptr;
    onStartCallback = nullptr;
    onFinishCallback = nullptr;
    onFailCallback = nullptr;
    delete currentRecorder;
    currentRecorder = nullptr;
    ALOGD("SequenceRecorder finalize！");
}
